import Core.Basic
from Core.package import *




class Worker_Thread(QThread):
    thread_task_data = Signal(dict)
    def __init__(self, parent = None):
        super().__init__(parent)

        self.task_data = dict()

    
    def run(self):
        driver = Core.Basic.GlobalVar.driver
        # 定义变量,用来获取子线程采集的数据
        Title = str()
        Main_Images_Url = list()
        Main_Video_Url = list()
        Sku_List = list()
        Detail_Images_Url = list()
        Product_Parm_List = list()
        From_Website = "DouYinZhiBo"
        Src_Product_Url = driver.current_url



        try:
            # 1.获取商品的标题
            title_xpaths = [
                "//div[contains(@class,'content-transition')]//span[@title='']",
                "//span[@title='']"
            ]
            for xpath in title_xpaths:
                try:
                    Title = driver.find_element(by=By.XPATH, value=xpath).text
                except Exception as e:
                    print(f"提示: Xpath '{xpath}' 查找失败!")

                # 如果获取到标题,则跳出循环
                if Title:
                    print(f"提示 : 获取标题成功 - {Title}")
                    break



            # 2.获取商品的主图
            main_images_xpath = [
                "//div[contains(@class,'swiper-slide')]/div/img"
            ]
            for xpath in main_images_xpath:
                try:
                    elements = driver.find_elements(by=By.XPATH,value=xpath)
                    for element in elements:
                        url = element.get_attribute("src")
                        if url in Main_Images_Url:  # 确保主图列表中不重复
                            continue
                        Main_Images_Url.append(url)
                except TimeoutException as e:
                    print(f"提示 : Xpath : {xpath} 获取主图元素失败!")
                
                # 如果获取到主图,则跳出循环
                if Main_Images_Url:
                    print(f"提示 : 获取主图成功!获取到的主图数量为 : {len(Main_Images_Url)}")
                    break



            # 3.获取商品的主图视频
            Main_Video_Url = ""



            # 4.提取 sku 列表
            sku_url_list_xpath = [
                "//*[contains(@class,'ufz0AqTE') and .//img]",
                "//div[contains(@class,'content-transition')]//div[contains(text(),'分类')]/following-sibling::div/div"
            ]
            for xpath in sku_url_list_xpath:
                try:
                    elements = driver.find_elements(by=By.XPATH,value=xpath)
                    for element in elements:
                        sku_img_url = element.find_element(by=By.XPATH,value=".//img").get_attribute('src').replace("resize:300","resize:1200")
                        sku_label = element.find_element(by=By.XPATH,value="./div[not(descendant::*)]").text
                        Sku_List.append({"sku_label":sku_label,"sku_img_url":sku_img_url})
                except Exception as e:
                    print(f"提示 : Xpath : {xpath} 获取 sku 分类元素失败!")
                
                # 如果获取到 sku 分类,则跳出循环
                if Sku_List:
                    print(f"提示 : 获取 sku 分类成功!获取到 sku 分类数量为 : {len(Sku_List)}")
                    [print(f"\t\tsku_label : {item['sku_label']}\n\t\tsku_img_url : {item['sku_img_url']}") for item in Sku_List]
                    break



            # 5.获取详情图url
            detail_img_xpath = [
                "//div[contains(@class,'content-transition')]//img[@class='nPQ6wC4v']"
            ]
            for xpath in detail_img_xpath:
                elements = driver.find_elements(by=By.XPATH,value=xpath)
                
                # 此处出现问题,获取不到具体的图片链接地址.
                for element in elements:
                    url = element.get_attribute("src")
                    Detail_Images_Url.append(url)
                    
                # 如果获取到详情图,则跳出循环
                if Detail_Images_Url:
                    print(f"提示 : 获取详情图成功!获取到详情图数量为 : {len(Detail_Images_Url)}")
                    # [print(f"\t\tindex : {index} url : {url}") for index,url in enumerate(detail_images_url,start=1)]
                    break



            # 6.获取商品的参数
            product_parm_xpath = [
                "//div[contains(@class,'content-transition')]//div[@class='hIRfCKxu']",
            ]
                # 获取所有的参数列表
            for xpath in product_parm_xpath:
                parms_elements = driver.find_elements(by=By.XPATH,value=xpath)
                if parms_elements:
                    break

            for element in parms_elements:
                parm_label = element.find_element(by=By.XPATH,value=f"./*[position() = 1]").text
                parm_value = element.find_element(by=By.XPATH,value=f"./*[position() = 2]").text
                parms_elements != "" and Product_Parm_List.append({"parm_label":parm_label,"parm_value":parm_value})



            # 整合数据
            self.task_data = {
                "title":Title,
                "main_images_list":Main_Images_Url,
                "main_video_url":Main_Video_Url,
                "sku_list":Sku_List,
                "detail_images_url":Detail_Images_Url,
                "product_parm_list":Product_Parm_List,
                "from_website":From_Website,
                "src_product_url":Src_Product_Url
            }



        except Exception as e:
            print(f"提示 : 员工线程任务发生错误!\n\
                    错误信息: {e}")
        finally:
            self.thread_task_data.emit(self.task_data)




















    def __delattr__(self, name):
        print(f"提示 : 子任务子线程运行结束!正在销毁资源 {self}")
        return super().__delattr__(name)
    


class Staff_Get_Data_DouYin_ZhiBo(QObject):
    Start_Task = Signal()   # 任务开始信号,启动任务时,请发送此信号
    Task_Finish = Signal()   # 任务完成信号,任务结束时候,请发送此信号
    Current_Completion_Process = Signal(int)
    Emergency_Stop = Signal()  # 紧急停止信号
    OnlyRun = Signal()  # 仅运行信号

    def __init__(self, parent=None):
        super().__init__(parent)
        self.Start_Task.connect(self.RunTask)
        
    @Slot(str)
    def slot_fun(self,text):
        print(f"我是槽函数,我是 {text}")

    # 设置员工属性
    def Set_Staff_Attribute(self,**kwargs):
        """设置员工对象的属性，用于后续任务执行
        """
        for key, value in kwargs.items():
            setattr(self, key, value)
        print(f"已设置属性: {kwargs.keys()}")

    def RunTask(self):

        # 获取需要操作的 主线程 窗口的 UI 对象
        # 使用 self.parent() 获取父对象
        self.parent_widget = self.parent()
        if self.parent_widget is None:
            print(f"提示 : 父对象为空!\n请将创建员工对象时,将父对象作为参数传入!")
            return
        # 获取 任务按钮 UI 控件对象
        self.task_button_object_name = "pushButton_get_data_douyin_zhibo"
        self.task_button : QPushButton = self.parent().findChild(QPushButton,self.task_button_object_name)
        if self.task_button is None:
            print(f"提示 : 程序无法找到 {self.task_button_object_name} 对应的按钮!")
            print(f"提示 : 子任务结束!")
            return
        self.textedit_get_datas_object_name = "textEdit_get_datas"
        self.textedit_get_datas : QTextEdit = self.parent().findChild(QTextEdit,self.textedit_get_datas_object_name)
        if self.textedit_get_datas is None:
            print(f"提示 : 程序无法找到 {self.textedit_get_datas_object_name} 对应的文本框!")
            print(f"提示 : 子任务结束!")
            return



        # 创建子线程
        self.workerthread = Worker_Thread()



        # 绑定信号
        self.workerthread.finished.connect(lambda : QMessageBox.information(self.parent_widget,"提示","采集 [抖音直播商品] 任务完成!"))
        self.workerthread.finished.connect(lambda : self.Task_Finish.emit())    # 子线程运行结束代表该员工类的任务结束
        self.workerthread.finished.connect(lambda : self.workerthread.quit())   # 线程结束，销毁线程
        self.workerthread.finished.connect(lambda : self.deleteLater())
        self.workerthread.finished.connect(lambda : self.task_button.setEnabled(True))
        self.workerthread.thread_task_data.connect(lambda task_data: self.textedit_get_datas.setText(json.dumps(task_data,ensure_ascii=False,indent=4)))


        # 启动子线程,开始执行任务
        self.task_button.setEnabled(False)
        self.workerthread.start()
        

        


















if __name__ == "__main__":
    import sys
    from PySide6.QtWidgets import QApplication
    app = QApplication(sys.argv)
    # 编写 控制台 程序
    staff = Staff_Get_Data_DouYin_ZhiBo(app)
    staff.RunTask()
    
    sys.exit(app.exec_())